/**
 * Require: <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
 **/

function Time(hours, minutes, negative) {
    this.hours = hours || 0;
    this.minutes = minutes || 0;
    this.negative = negative || false;
    if(!Number.isInt(this.hours) || !Number.isInt(this.minutes)) throw new Error("Invalid time");
}

Time.prototype.inMinutes = function() {
    var signal = this.negative ? -1 : 1;
    return  (this.hours * 60 + this.minutes )* signal;
};

Time.prototype.plus = function(time) {
    var m1 = this.inMinutes();
    var m2 = time.inMinutes();
    return Time.fromMinutes(m1+m2);
};

Time.prototype.minus = function(time) {
    var m1 = this.inMinutes();
    var m2 = time.inMinutes();
    return Time.fromMinutes(m1-m2);
};

Time.prototype.toString = function() {
    var signal = this.negative ? '-' : '';
    return signal + this.hours.toString().pad(2) + ':' + this.minutes.toString().pad(2);
};

/* static */

Time.fromMinutes = function(minutes) {
    var negative = minutes < 0;
    minutes = Math.abs(minutes);
    var h = parseInt(minutes/60, 10);
    var m = minutes - (h*60);
    return new Time(h,m, negative);
}

Time.fromString = function(hhmmAsText) {
    var negative = (hhmmAsText.indexOf('-') === 0);
    if(hhmmAsText.indexOf(':') < 0) throw new Error("Invalid time");
    var hhmm = hhmmAsText.split(':').map(function(it){ return parseInt(it, 10); });
    if(!Number.isInt(hhmm[0]) || !Number.isInt(hhmm[1])) throw new Error("Invalid time");
    return new Time(hhmm[0],hhmm[1], negative);
}

Time.isTime = function (hhmmAsText) {
    try {
        var time = Time.fromString(hhmmAsText);
        return Number.isInt(time.hours) && Number.isInt(time.minutes);
    } catch(any) { return false; }
}

Time.now = function() {
    var dt = new Date();
    return new Time(dt.getHours(), dt.getMinutes());
};